package epoch.game.core.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * 压缩工具
 * 
 * @author will
 * @date 2015年6月24日 下午2:39:56
 */
public final class ZLibUtils
{
  private static final Logger log = LogManager.getLogger(ZLibUtils.class);
  
  /**
   * 压缩
   * @param bytes
   * @return
   */
  public static byte[] compress(byte[] bytes)
  {
    byte[] zipBytes = new byte[0];
    Deflater deflater = new Deflater();
    deflater.reset();
    deflater.setInput(bytes);
    deflater.finish();
    ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length);
    try
    {
      byte[] tempBytes = new byte[1024];
      while (!deflater.finished())
      {
        int i = deflater.deflate(tempBytes);
        out.write(tempBytes, 0, i);
      }
      zipBytes = out.toByteArray();
      try
      {
        out.close();
      }
      catch (IOException e)
      {
        log.error(e, e);
      }
      deflater.end();
    }
    catch (Exception e)
    {
      zipBytes = bytes;
      log.error(e, e);
    }
    finally
    {
      try
      {
        out.close();
      }
      catch (IOException e)
      {
        log.error(e, e);
      }
    }
    return zipBytes;
  }
  
  public static void compress(byte[] bytes, OutputStream output)
  {
    DeflaterOutputStream out = new DeflaterOutputStream(output);
    try
    {
      out.write(bytes, 0, bytes.length);
      out.finish();
      out.flush();
    }
    catch (IOException e)
    {
      log.error(e, e);
    }
  }
  
  public static byte[] decompress(byte[] bytes)
  {
    byte[] resultBytes = new byte[0];
    Inflater inflater = new Inflater();
    inflater.reset();
    inflater.setInput(bytes);
    ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length);
    try
    {
      byte[] tempBytes = new byte[1024];
      while (!inflater.finished())
      {
        int i = inflater.inflate(tempBytes);
        out.write(tempBytes, 0, i);
      }
      resultBytes = out.toByteArray();
      try
      {
        out.close();
      }
      catch (IOException e)
      {
        log.error(e, e);
      }
      inflater.end();
    }
    catch (Exception e)
    {
      resultBytes = bytes;
      log.error(e, e);
    }
    finally
    {
      try
      {
        out.close();
      }
      catch (IOException e)
      {
        log.error(e, e);
      }
    }
    return resultBytes;
  }
  
  public static byte[] decompress(InputStream input)
  {
    InflaterInputStream inflater = new InflaterInputStream(input);
    ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
    try
    {
      int i = 1024;
      byte[] arrayOfByte = new byte[i];
      while ((i = inflater.read(arrayOfByte, 0, i)) > 0) {
        out.write(arrayOfByte, 0, i);
      }
    }
    catch (IOException e)
    {
      log.error(e, e);
    }
    return out.toByteArray();
  }
}
